﻿using System.Reflection;
using ExcelUnity.Core;
using ExcelUnity.Exporter.Attributes;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;

namespace ExcelUnity.Exporter;

public class DefaultExcelExporter : IExcelExporter
{
    public void Export<T>(List<T> data,string filePath)
    {
        using var outStream = new FileStream(filePath, FileMode.Create, FileAccess.Write);
        Export(data,outStream);
    }

    public byte[] Export<T>(List<T> data)
    {
        using var stream = new MemoryStream();
        Export(data,stream);
        return stream.ToArray();
    }

    public void Export<T>(List<T> data,Stream stream)
    {
        if (stream == null) throw new ArgumentNullException("stream is null");
        ExportExcel(data,stream);
    }

    private void ExportExcel<T>(List<T> data,Stream stream, string title = "导出记录")
    {
        var workBook = new XSSFWorkbook();

        try
        {
            var sheet = workBook.CreateSheet();
            var columnProperties = CreateColumnProperties(typeof(T));

            //创建Title
            var rowIndex = 0;
            if (!string.IsNullOrEmpty(title))
            {
                var row = sheet.CreateRow(0);
                var cell =  row.CreateCell(0);
                cell.SetCellValue(title);
      
                var cellStyle = workBook.CreateCellStyle();
                cellStyle.Alignment = HorizontalAlignment.Center;
                cellStyle.VerticalAlignment = VerticalAlignment.Center;
                var font = workBook.CreateFont();
                font.IsBold = true;
                font.FontName = "微软雅黑";
                cellStyle.SetFont(font);
                cell.CellStyle = cellStyle;
                sheet.AddMergedRegion(new CellRangeAddress(0, rowIndex++, 0, columnProperties.Count - 1));
            }

            //创建header
            var excelRow = sheet.CreateRow(rowIndex++);
            foreach (var property in columnProperties)
            {
                var excelCell = excelRow.CreateCell(property.ColumnIndex);
                excelCell.SetCellValue(property.Name);
            }

            //填充行
            foreach (var item in data)
            {
                var row = sheet.CreateRow(rowIndex++);
                foreach (var property in columnProperties)
                {
                    var excelCell = row.CreateCell(property.ColumnIndex);
                    excelCell.SetCellValue(property.GetCellValue(item));
                }
            }
            workBook.Write(stream);
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            workBook?.Close();
        }
    }

    private static List<ColumnProperty> CreateColumnProperties(Type type)
    {
        var columnProperties = type.GetProperties()
            .Where(x => x.GetCustomAttribute(typeof(IgnoreColumnAttribute)) is null)
            .Select(m => new ColumnProperty(m))
            .ToList();

        for (int i = 0; i < columnProperties.Count; i++)
            columnProperties[i].ColumnIndex = i;

        return columnProperties;
    }
}